package com.radar.task.无线电厂;

import cn.hutool.core.date.DateUtil;
import cn.hutool.core.io.FileUtil;
import com.radar.common.DateConstants;
import com.radar.io.LatLonRadar;
import com.radar.task.cd.Constants;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.io.filefilter.RegexFileFilter;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
import org.springframework.stereotype.Service;

import java.io.File;
import java.util.Comparator;
import java.util.Date;
import java.util.List;
import java.util.stream.Collectors;

@Component
@Slf4j
@Service(value = "wxdc_forecast_task")
public class ForecastTask {

    @Value("${step:2}")
    private int step;

//    @Scheduled(cron = "0 0/2 * * * ? ")

    /**
     * 覆盖代码注释
     */
    public void readlonlat() {
        long time = System.currentTimeMillis();
        // Z_RADA_C_BABJ_(\\d{14})_P_ACHN.CREF000.20210318.0300.latlon
        log.info("开始轮询 无线电厂雷达 latlon 数据");
        List<File> files = FileUtil.loopFiles(Constants.rootPath, new RegexFileFilter("^Z_RADA_C_BABJ_(\\d{14})_P_ACHN.CREF000.(\\d{8}).(\\d{6}).latlon$")).stream()
                .sorted(Comparator.comparingLong(i -> Long.parseLong(i.getName().split("_")[4])))
                .collect(Collectors.toList());
        for (File file : files) {
            String next = file.getName();
            if (FileUtil.exist(Constants.tmpPath + file.getName() + ".OK")) {
                continue;
            } else {
                FileUtil.touch(Constants.tmpPath + file.getName() + ".OK");
            }
            int step = 6;
            String pre = null;
            // find pre
//            long dt = Long.parseLong(file.getName().substring(2, 2 + 14));
//            long min = Long.MAX_VALUE;
//            for (int i = 0; i < files.size(); i++) {
//                if (files.get(i).getName().equals(file.getName())) {
//                    continue;
//                }
//                if (!FileUtil.exist(files.get(i).getAbsolutePath() + ".OK")) {
//                    continue;
//                }
//                long n = Long.parseLong(files.get(i).getName().substring(2, 2 + 14));
//                if (n >= dt) {
//                    continue;
//                }
//                if (dt - n < 1000 * 60 * 12 && dt - n < min) {
//                    min = dt - n;
//                    pre = files.get(i).getName();
//                    step = (int) ((DateUtil.parse(file.getName().substring(2, 2 + 14), DateConstants.DATE_TIME_FORMAT_YYYYMMDDHHMISS).getTime() -
//                                                DateUtil.parse(files.get(i).getName().substring(2, 2 + 14), DateConstants.DATE_TIME_FORMAT_YYYYMMDDHHMISS).getTime()) / (1000 * 60.0));
//                }
//            }

            try {
                log.info("start parse pre radar file : {} , step : {} ,next radar file : {}", pre, step, next);
                parselatlon(file);
            } catch (Exception e) {
                e.printStackTrace();
                log.info("parse radar erro file : {}", next);
            }
        }
        log.info("sum time : {}", System.currentTimeMillis() - time);
    }

    /**
     * 覆盖代码注释
     * @param next
     * @throws Exception
     */
    public void parselatlon(File next) throws Exception {
        String output = Constants.ncPath + File.separator;
        FileUtil.mkdir(output);
        String s = next.getName().split("\\.")[2] + next.getName().split("\\.")[3];
        Date date = DateUtil.parse(s, DateConstants.DATE_TIME_FORMAT_YYYYMMDDHHMISS);

        FileUtil.mkdir(output + DateUtil.format(date, DateConstants.DATE_FORMAT_YYYYMMDDHHMM));

        LatLonRadar radar = new LatLonRadar();
        radar.parse(next.getAbsolutePath());
        radar.forecastItem(output + DateUtil.format(DateUtil.offsetMinute(date, -6), DateConstants.DATE_FORMAT_YYYYMMDDHHMM),
                output + DateUtil.format(date, DateConstants.DATE_FORMAT_YYYYMMDDHHMM), step);

//        CinradRadar nextCinrad = new CinradRadar();
//        nextCinrad.setNetcdfFile(output + date + File.separator + next + ".nc");
//        nextCinrad.parse(input + next, CinradType.RADAR_382);
//
//        // 生成CR
//        RadarGridData cr = nextCinrad.radar.getCR();
//        RasterMap rasterMap = new RasterMap(nextCinrad.radar);
//
//
//        // draw cr
//        BufferedImage bufferedImage = rasterMap.drawSingleRaster(MathCommon.decode(cr.radarData, ProductType.REF), ProductType.REF, new Color(0, 0, 0, 0));
//        ImageIO.write(bufferedImage, "png", new File(output + date + File.separator + date + "_CR_0.png"));
//        log.info("draw cr radar end file : {}", next);
//        // draw gray
//        double[][] gray = MathCommon.decode(cr.radarData, ProductType.REF);
//        gray = Cacl.nineMedianFilter(gray);
//        gray = Cacl.nineMedianFilter(gray);
//        gray = Cacl.nineMedianFilter(gray);
//        bufferedImage = rasterMap.drawSingleRaster(gray, ProductType.REFGRAY);
//        ImageIO.write(bufferedImage, "png", new File(output + date + File.separator + "CR_GRAY.png"));
//        log.info("draw cr_gray end radar file : {}", next);
//        // find pre GRAY
//        if (pre != null) {
//            forecast(output + pre.substring(2, 19) + File.separator + "CR_GRAY.png",
//                    output + date + File.separator + "CR_GRAY.png",
//                    offset, cr, nextCinrad, next);
//            log.info("start forecast pre radar file : {} next radar file : {}", pre, next);
//        }
//        // output storms
//        RefObj<Integer> count1 = new RefObj<>(0);
//        int step = 2;
//        double[][] decode = MathCommon.decode(cr.radarData, ProductType.REF);
//        double[][] data = new double[decode.length / step][decode[0].length / step];
//        for (int i = 0; i < data.length; i++) {
//            for (int j = 0; j < data[0].length; j++) {
//                data[i][j] = decode[i * step][j * step];
//            }
//        }
//        List<Storms.StormDt> list = Storms.getStorms(data, step, count1, 28, nextCinrad);
//        Gson gson = new Gson();
//        // 判断上一个json 是否存在
//        if (pre != null) {
//            String predt = pre.substring(2, 19);
//            CinradRadar preCinrad = new CinradRadar();
//            preCinrad.setNetcdfFile(output + predt + File.separator + pre + ".nc");
//            preCinrad.parse(input + pre, CinradType.RADAR_382);
//            double[][] decodePre = MathCommon.decode(preCinrad.radar.getCR().radarData, ProductType.REF);
//            double[][] dataPre = new double[decodePre.length / step][decodePre[0].length / step];
//            for (int i = 0; i < dataPre.length; i++) {
//                for (int j = 0; j < dataPre[0].length; j++) {
//                    dataPre[i][j] = decodePre[i * step][j * step];
//                }
//            }
//            RefObj<Integer> count = new RefObj<>(0);
//            List<Storms.StormDt> list0 = Storms.getStorms(dataPre, step, count, 28, preCinrad);
//            // 计算风暴外推
//            List<Storms.StormDt> track = Storms.track(list0, list, nextCinrad);
//            if (track != null) {
//                list = track;
//            }
//            preCinrad.radar.close();
//        }
//        list.forEach(z -> {
//            z.setCenter(new PointD(cr.xArray[(int) z.getCenter().Y], cr.yArray[cr.yArray.length - 1 - (int) z.getCenter().X]));
//            z.getBoundary().forEach(point -> {
//                double x = cr.xArray[(int) point.Y];
//                double y = cr.yArray[cr.yArray.length - 1 - (int) point.X];
//                point.X = x;
//                point.Y = y;
//            });
//            z.getContain().forEach(point -> {
//                double x = cr.xArray[(int) point.Y];
//                double y = cr.yArray[cr.yArray.length - 1 - (int) point.X];
//                point.X = x;
//                point.Y = y;
//            });
//        });
//        log.info("write storm and extent radar file : {}", next);
//        FileUtil.writeString(gson.toJson(list), new File(output + date + File.separator + date + "_strom.json"), Charset.defaultCharset());
//        FileUtil.writeString(cr.getXMin() + ";" + cr.getXMax() + ";" + cr.getYMin() + ";" + cr.getYMax(), new File(output + date + File.separator + date + "_extent.json"), Charset.defaultCharset());
//        nextCinrad.radar.flush();
//        FileUtil.touch(OKFile);
    }

//    public void forecast(String preImg, String nextImg, int offset, RadarGridData cr, CinradRadar cinradRadar, String filename) throws IOException {
//        String output = Constants.ncPath + File.separator;
//        String date = filename.substring(2, 19);
//        Mat ff1 = opencv_imgcodecs.imread(preImg);
//        Mat ff2 = opencv_imgcodecs.imread(nextImg);
//        Mat prvs = ff1.clone();
//        Mat next = ff1.clone();
//        opencv_imgproc.cvtColor(ff1, prvs, opencv_imgproc.COLOR_BGR2GRAY);
//        opencv_imgproc.cvtColor(ff2, next, opencv_imgproc.COLOR_BGR2GRAY);
//
//        int w = prvs.size().get(0);
//        int h = prvs.size().get(1);
//        double[][] pre = new double[h][w];
//        double[][] nex = new double[h][w];
//        Indexer indexer = prvs.createIndexer();
//        Indexer indexer1 = next.createIndexer();
//        for (int i = 0; i < h; i++) {
//            for (int j = 0; j < w; j++) {
//                pre[i][j] = indexer.getDouble(i, j);
//                if (pre[i][j] == 255) {
//                    pre[i][j] = 0;
//                }
//                nex[i][j] = indexer1.getDouble(i, j);
//                if (nex[i][j] == 255) {
//                    nex[i][j] = 0;
//                }
//            }
//        }
//        double[][][] cacl = DenseLucaskanade.cacl(new double[][][]{pre, nex});
//        double[][] u = cacl[0];
//        double[][] v = cacl[1];
//        for (int i = 0; i < h; i++) {
//            for (int j = 0; j < w; j++) {
//                u[i][j] = u[i][j] * (3.0 / offset);
//                v[i][j] = v[i][j] * (3.0 / offset);
//            }
//        }
//        double[][] decode = MathCommon.decode(cr.radarData, ProductType.REF);
//        if (decode.length == u.length && decode[0].length == u[0].length) {
//
//        } else {
//            double[][] z = new double[u.length][u[0].length];
//            for (int i = 0; i < h; i++) {
//                for (int j = 0; j < w; j++) {
//                    if (i >= decode.length || j >= decode[0].length) {
//                        z[i][j] = GisConstants.UNDEF;
//                    } else {
//                        z[i][j] = decode[i][j];
//                    }
//                }
//            }
//            decode = z;
//        }
//        SemiLagrangian semiLagrangian = new SemiLagrangian();
//        int t = 20;
//        float[][][] extrapolate = semiLagrangian.extrapolate(MathCommon.doubleToFloat(decode), MathCommon.doubleToFloat(u), MathCommon.doubleToFloat(v), t);
//        cinradRadar.radar.writeSemiLagrangian(extrapolate, 5, t);
//        for (int i = 0; i < t; i++) {
//            BufferedImage bufferedImage;
//            for (int j = 0; j < u.length; j++) {
//                for (int k = 0; k < u[0].length; k++) {
//                    extrapolate[i][j][k] = extrapolate[i][j][k] == 0 || extrapolate[i][j][k] == Float.NaN ? GisConstants.UNDEF : extrapolate[i][j][k];
//                }
//            }
//            RasterMap rasterMap = new RasterMap(cinradRadar.radar);
//            bufferedImage = rasterMap.drawSingleRaster(MathCommon.floatToDouble(extrapolate[i]), new Color(0, 0, 0, 0));
//            ImageIO.write(bufferedImage, "png", new File(output + date + File.separator + date + "_CR_" + (i + 1) + ".png"));
//        }
//    }

}
